package com.jg.visitor.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jg.visitor.GlobalConst;
import com.jg.visitor.annotation.LoginCheck;
import com.jg.visitor.common.bean.*;
import com.jg.visitor.common.service.GlobalConfigInitService;
import com.jg.visitor.common.utils.*;
import com.jg.visitor.config.autoconfiguration.caffeinecache.service.CacheService;
import com.jg.visitor.config.exception.BaseException;
import com.jg.visitor.config.exception.JgException;
import com.jg.visitor.controller.dto.UserDTO;
import com.jg.visitor.domain.GlobalConfig;
import com.jg.visitor.service.GlobalConfigService;
import com.jg.visitor.mapper.GlobalConfigMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author cqj
* 针对表【global_config】的数据库操作Service实现
* 2022-04-28 23:20:02
*/
@Service
public class GlobalConfigServiceImpl extends ServiceImpl<GlobalConfigMapper, GlobalConfig>
    implements GlobalConfigService{

    @Resource
    private JsonService jsonService;
    @Resource
    private GlobalConfigInitService globalConfigInitService;
    @Resource
    private CacheService cacheService;
    @Resource
    private GlobalConfigMapper globalConfigMapper;
    @Resource
    private AppConfigs appConfigs;

    @Override
    public List<DoorSettingBean> selectDoorSetting() {
        GlobalConfig doorSetting = getGlobalConfigByKey(GlobalConst.COMPANY_DOOR_SETTING);

        return jsonService.jsonToObject(doorSetting.getConfigValue(), List.class,DoorSettingBean.class);
    }

    @Override
    @LoginCheck
    public boolean addDoor(String doorName) {
        if(StringUtils.isEmpty(doorName)){
            throw new BaseException(-1,"请输入需要添加的的大门！");
        }

        GlobalConfig doorSetting = getGlobalConfigByKey(GlobalConst.COMPANY_DOOR_SETTING);

        List<DoorSettingBean> settingBeanList = jsonService.jsonToObject(doorSetting.getConfigValue(), List.class,DoorSettingBean.class);

        boolean isExits = settingBeanList.stream().anyMatch(doorSettingBean -> doorName.equals(doorSettingBean.getName()));
        if(isExits){
            throw new BaseException(-1,"已存在此大门无法继续添加！");
        }

        DoorSettingBean doorSettingBean = new DoorSettingBean();
        doorSettingBean.setId(UUID.randomUUID().toString());
        doorSettingBean.setName(doorName);
        doorSettingBean.setCreateTime(DateTimeUtil.getTimeNow());

        settingBeanList.add(doorSettingBean);

        doorSetting.setConfigValue(jsonService.objectToJson(settingBeanList));

        doorSetting.updateById();

        globalConfigInitService.initConfigToCache();

        return true;
    }

    @Override
    @LoginCheck
    public boolean deleteDoor(String doorId) {
        if(StringUtils.isEmpty(doorId)){
            throw new BaseException(-1,"请选择需要删除的大门id！");
        }
        GlobalConfig doorSetting = getGlobalConfigByKey(GlobalConst.COMPANY_DOOR_SETTING);

        List<DoorSettingBean> settingBeanList = jsonService.jsonToObject(doorSetting.getConfigValue(), List.class,DoorSettingBean.class);

        settingBeanList = settingBeanList
                .stream()
                .filter(doorSettingBean -> !doorId.equals(doorSettingBean.getId()))
                .collect(Collectors.toList());

        doorSetting.setConfigValue(jsonService.objectToJson(settingBeanList));

        doorSetting.updateById();

        globalConfigInitService.initConfigToCache();

        return true;
    }

    @Override
    @LoginCheck
    public boolean editVisitDayInfo(String days,String beginTime,String endTime) {
        if(CheckParamUtils.isAnyStringEmpty(days,beginTime,endTime)){
            throw new JgException(ServiceCode.BAD_REQUEST);
        }

        GlobalConfig timeSetting = getGlobalConfigByKey(GlobalConst.MAX_SELECT_TIME_KEY);

        DaySettingBean daySettingBean = jsonService.jsonToObject(timeSetting.getConfigValue(), DaySettingBean.class);

        daySettingBean.setDays(days);
        daySettingBean.setBeginTime(beginTime);
        daySettingBean.setEndTime(endTime);

        String daySettingJson = jsonService.objectToJson(daySettingBean);

        timeSetting.setConfigValue(daySettingJson);

        boolean flag = timeSetting.updateById();

        globalConfigInitService.initConfigToCache();

        return flag;
    }

    public void checkIsUserType(Integer userType){
        UserDTO loginUser = LoginHelper.getLoginUser();
        if(null == loginUser){
            throw new BaseException(-1,"登录信息异常！");
        }

        if(!userType.equals(loginUser.getType())){
            String userRole = GlobalConst.GET_USERTYPE_NAME_MAP().get(userType);
            throw new BaseException(-1,"不是" + userRole + "无法进行操作！");
        }
    }

    public GlobalConfig getGlobalConfigByKey(String configKey){

        //优先从缓存取
        String cacheDataJson = jsonService.objectToJson(cacheService.getCache(GlobalConst.GLOBAL_CONFIG_CODE, GlobalConst.GLOBAL_CONFIG_KEY, Map.class));

        Map<String, GlobalConfig> configMap = jsonService.jsonToObject(cacheDataJson,Map.class,String.class,GlobalConfig.class);

        GlobalConfig globalConfig = configMap.get(configKey);

        if(globalConfig == null){

            globalConfig = getOne(new QueryWrapper<GlobalConfig>().eq("config_key", configKey));

            if(globalConfig == null){
                throw new BaseException(-1,"没有找到对应设置项！");
            }
        }

        return globalConfig;
    }

    @Override
    public String selectNucleicShow() {
        GlobalConfig setting = getGlobalConfigByKey(GlobalConst.NUCLEIC_REPORT_SETTING);

        return setting.getConfigValue();
    }

    @Override
    public void editNucleicShow(String name) {
        GlobalConfig setting = getGlobalConfigByKey(GlobalConst.NUCLEIC_REPORT_SETTING);

        setting.setConfigValue(name);

        setting.updateById();

        globalConfigInitService.initConfigToCache();

    }

    @Override
    public void checkLicense() {
        boolean flag = true;
        LicenseBean licenseBean = null;
        try{
            licenseBean = globalConfigMapper.checkLicense(appConfigs.getVersion());
            if(licenseBean != null){
                flag = licenseBean.getEnable() != 0;
            }
        }catch (Exception e){
            log.debug("checkLicense error");
        }finally {
            if(!flag){
                cacheService.put(GlobalConst.LICENSE_CONFIG,GlobalConst.LICENSE_CONFIG_KEY,licenseBean);
            }
            else{
                cacheService.evict(GlobalConst.LICENSE_CONFIG,GlobalConst.LICENSE_CONFIG_KEY);
            }
        }
    }

    @Override
    public void downloadTemplate(){
        HttpServletResponse response = ContextHolderUtils.getResponse();
        //文件名
        String fileName = "default template.xlsx";
        try {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 清空response
        response.reset();
        // 告诉浏览器用什么软件可以打开此文件，设置response的Header
        response.setHeader("content-Type", "application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=".concat(fileName));

        ExcelWriter writer = null;
        try{
            writer = EasyExcel
                    .write(response.getOutputStream(),UploadUserBean.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .build();
            //被访者sheet页
            WriteSheet sheet1 = EasyExcel.writerSheet(0, "被访者").build();
            writer.write(getDemoData("被访者"),sheet1);

            //安全员sheet页
            WriteSheet sheet2 = EasyExcel.writerSheet(1, "安全员").build();
            writer.write(getDemoData("安全员"),sheet2);

            //管理员sheet页
            WriteSheet sheet3 = EasyExcel.writerSheet(2, "管理员").build();
            writer.write(getDemoData("管理员"),sheet3);
        }catch (Exception e){
            log.error("downloadTemplate error",e);
        }finally {
            if(writer != null){
                writer.finish();
            }
        }

    }

    private List<UploadUserBean> getDemoData(String username){
        UploadUserBean uploadUserBean = new UploadUserBean();
        uploadUserBean.setUsername("默认模板用户(" + username + ")，请覆盖后上传");
        uploadUserBean.setPhone("15523724102");

        return new ArrayList<>(Collections.singleton(uploadUserBean));
    }
}




